/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frbyte_buffer.c                                    */
/*  NOTE      = 数据包移位、读取                                   */
/*  DATE      = 2014/12/11 guojq                                   */
/*******************************************************************/
#if defined(FRLINUX4) || defined(FRLINUX5)
    #include "endian_dbg.h"
#else
    #include <endian.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "frcomm.h"
#include "frmem.h"
#include "frlist.h"
#include "frbyte_buffer.h"
#include "frhex_dump.h"

Frbyte_Packet *bytebuff_creat(void)
{
    Frbyte_Packet *p_packet = NULL;
    
    p_packet = (Frbyte_Packet *)frmalloc(sizeof(Frbyte_Packet));
    if (!p_packet)
        return NULL;
    
    memset(p_packet, 0x00, sizeof(Frbyte_Packet));
    p_packet->p_lst_bytebuffer = frlist_create();
    p_packet->pos_index = 0;
    
    return p_packet;
}

FR_STATIC void __bytebuff_node_free(Frlist_node* node)
{
    Frbyte_buffer *p_byte_buffer = NULL;

    if (node == NULL || node->data == NULL)
        return;
    p_byte_buffer = (Frbyte_buffer *)node->data;
    if (p_byte_buffer->p_buf)
        frfree(p_byte_buffer->p_buf);
    frfree(p_byte_buffer);
}

void bytebuff_free(Frbyte_Packet **pp_packet)
{
    if (pp_packet && *pp_packet)
    {
        frlist_destroy((*pp_packet)->p_lst_bytebuffer, __bytebuff_node_free);
        frfree(*pp_packet);
        *pp_packet = NULL;
    }
    
    return;
}

int bytebuff_length(Frbyte_Packet *p_packet)
{
    if (p_packet)
        return p_packet->ui_all_len;
    return 0;
}

int bytebuff_remaining(Frbyte_Packet *p_packet)
{
    if (p_packet)
        return p_packet->ui_remaining;
    return -1;
}

FR_STATIC int __packet_add_skip(Frbyte_Packet *p_packet, unsigned int ui_buf_len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    
    if (p_packet == NULL || ui_buf_len == 0)
        return FR_FAIL;
    
    p_node = FRLIST_LAST_NODE(p_packet->p_lst_bytebuffer);
    if (!p_node || !p_node->data)
        return FR_FAIL;
    
    p_bytebuffer = (Frbyte_buffer *)p_node->data;
    
    //2个空包叠加
    if (p_bytebuffer->p_buf == NULL)
    {
        p_bytebuffer->ui_len += ui_buf_len;
        return FR_SUCC;
    }
    //新加一个包，放在packet最后
    p_bytebuffer = (Frbyte_buffer *)frmalloc(sizeof(Frbyte_buffer));
    if (p_bytebuffer == NULL)
        return FR_FAIL;
    
    p_bytebuffer->p_buf = NULL;
    p_bytebuffer->ui_len = ui_buf_len;
    p_bytebuffer->pos = 0;
    
    p_node = frlist_node_create(p_bytebuffer);
    frlist_add_tail(p_packet->p_lst_bytebuffer, p_node);
    
    return FR_SUCC;
}

FR_STATIC int __packet_add(Frbyte_Packet *p_packet, char *p_buf, unsigned int ui_buf_len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;

    #ifdef FRDBG_COREDUMP
    if (frlist_size(p_packet->p_lst_bytebuffer) > 1000)
    {
        APM_COREDUMP;
    }
    #endif

    p_bytebuffer = (Frbyte_buffer *)frmalloc(sizeof(Frbyte_buffer));
    if (p_bytebuffer == NULL)
        return FR_FAIL;

    p_bytebuffer->p_buf = (char *)frmemdup(p_buf, ui_buf_len);
    p_bytebuffer->ui_len = ui_buf_len;
    p_bytebuffer->pos = 0;
    
    p_node = frlist_node_create(p_bytebuffer);
    frlist_add_tail(p_packet->p_lst_bytebuffer, p_node);
    
    return FR_SUCC;
}

int bytebuff_add(Frbyte_Packet *p_packet, char *p_buf, unsigned int ui_buf_len)
{
    if (p_packet == NULL || p_buf == NULL || ui_buf_len == 0)
        return FR_FAIL;
    
    if (p_packet->ui_skip_len)
    {
        if (p_packet->ui_skip_len >= ui_buf_len)
        {
            //如果有skip并且大于此包的大小。pos不变、p_buf不加入链表节点、若前一个就是空包，叠加空包
            if (__packet_add_skip(p_packet, ui_buf_len) == FR_FAIL)
                return FR_FAIL;
            p_packet->ui_all_len += ui_buf_len;
            p_packet->ui_remaining += ui_buf_len;
            p_packet->ui_skip_len -= ui_buf_len;
            //第一次的当前节点设置为第一个节点
            if (p_packet->p_node_index == NULL)
                p_packet->p_node_index = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
            
            return FR_SUCC;
        }
        else
            p_packet->ui_skip_len = 0;
    }
    if (__packet_add(p_packet, p_buf, ui_buf_len) == FR_FAIL)
        return FR_FAIL;
        
    p_packet->ui_all_len += ui_buf_len;
    p_packet->ui_remaining += ui_buf_len;
    //第一次的当前节点设置为第一个节点
    if (p_packet->p_node_index == NULL)
        p_packet->p_node_index = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    
    return FR_SUCC;
}

int bytebuff_set_skip(Frbyte_Packet *p_packet, size_t len)
{
    if (!p_packet)
        return FR_FAIL;
    
    p_packet->ui_skip_len += len;
    return FR_SUCC;
}

int bytebuff_skip(Frbyte_Packet *p_packet, size_t len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    int i_left = 0, i_pos_index = 0;
    
    if (!p_packet || !p_packet->p_node_index || len > p_packet->ui_remaining)
        return FR_FAIL;
    
    p_node = p_packet->p_node_index;
    p_bytebuffer = (Frbyte_buffer *)p_node->data;
    //跳过长度
    if (p_bytebuffer->pos + len <= p_bytebuffer->ui_len)
    {
        p_bytebuffer->pos += len;
        p_packet->ui_remaining -= len;
        return FR_SUCC;
    }
    //当前的包不够长，移到下一个包
    i_pos_index = p_packet->pos_index;
    i_left = p_bytebuffer->pos + len - p_bytebuffer->ui_len;
    p_bytebuffer->pos = 0;
    
    while (i_left != 0)
    {
        p_node = FRLIST_NEXT_NODE(p_node);
        if (p_node == NULL)
            return FR_FAIL;
        i_pos_index += 1;
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (i_left < p_bytebuffer->ui_len)
        {
            p_bytebuffer->pos = i_left;
            break;
        }
        p_bytebuffer->pos = 0;
        i_left -= p_bytebuffer->ui_len;
        //正好skip一个包的长度
        if (i_left == 0)
        {
            p_bytebuffer->pos = p_bytebuffer->ui_len;
            break;
        }
    }
    p_packet->pos_index = i_pos_index;
    p_packet->ui_remaining -= len;
    p_packet->p_node_index = p_node;

    return FR_SUCC;
}

int bytebuffer_backspace(Frbyte_Packet *p_packet, size_t len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    int i_left = len;
    int i_node_len = 0;
    unsigned int ui_pos_index = 0;

    if (!p_packet || !p_packet->p_node_index || len > p_packet->ui_all_len - p_packet->ui_remaining)
        return FR_FAIL;

    p_node = p_packet->p_node_index;
    ui_pos_index = p_packet->pos_index;
    p_bytebuffer = (Frbyte_buffer *)p_node->data;
    i_node_len = p_bytebuffer->pos;
    
    if (p_bytebuffer->pos >= i_left)
    {
        p_bytebuffer->pos -= i_left;
        
        p_packet->ui_remaining += i_left;
        return FR_SUCC;
    }
    while (1)
    {
        p_packet->ui_remaining += i_node_len;
        i_left -= i_node_len;
        if (i_left < 0)
            return FR_FAIL;
        ui_pos_index--;
        p_bytebuffer->pos = 0;
        p_node = frlist_node_idx(p_packet->p_lst_bytebuffer, ui_pos_index);
        if (p_node == NULL)
        {
            printf("====bytebuffer_backspace len=[%u], packet->pos_index=[%u], i_now_pos=[%u], remaining=[%u], ui_all_len=[%u]\n"
                , (unsigned int)len, p_packet->pos_index, ui_pos_index, p_packet->ui_remaining, p_packet->ui_all_len);
            return FR_FAIL;
        }
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        i_node_len = p_bytebuffer->ui_len;
        
        if (i_node_len >= i_left)
        {
            p_bytebuffer->pos = i_node_len - i_left;

            p_packet->p_node_index = p_node;
            p_packet->ui_remaining += i_left;
            p_packet->pos_index = ui_pos_index;
            return FR_SUCC;
        }
    }
    return FR_FAIL;
}

int bytebuff_rewind(Frbyte_Packet *p_packet)
{
    Frbyte_buffer *p_bytebuffer = NULL;
    
    if (p_packet == NULL)
        return FR_FAIL;
    
    if (p_packet->p_node_index)
    {
        p_bytebuffer = (Frbyte_buffer *)p_packet->p_node_index->data;
        p_bytebuffer->pos = 0;
    }
    p_packet->pos_index = 0;
    p_packet->ui_skip_len = 0;
    p_packet->ui_remaining = p_packet->ui_all_len;
    p_packet->p_node_index = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    
    return FR_SUCC;
}

int bytebuff_truncate(Frbyte_Packet *p_packet)
{
    Frbyte_buffer *p_bytebuffer = NULL;
    char *p_buff = NULL;
    int i_left = 0;
    
    if (!p_packet || !p_packet->p_node_index)
        return FR_FAIL;
        
    //当前位置的数据存储起来。
    p_bytebuffer = (Frbyte_buffer *)p_packet->p_node_index->data;
    i_left = p_bytebuffer->ui_len - p_bytebuffer->pos;
    
    //数据被破坏
    if (i_left < 0)
        return FR_FAIL;
    
    if (p_bytebuffer->p_buf)
    {
        if (i_left)
        {
            p_buff = (char *)frmemdup(p_bytebuffer->p_buf + p_bytebuffer->pos, i_left);
            if (!p_buff)
                return FR_FAIL;
        }
    }
    //释放当前位置之前的packet节点
    {
        int i_pos_index = p_packet->pos_index;
        Frbyte_buffer *p_bytebuffer_tmp = NULL;
        int i_pos = 0;
        Frlist_node *p_node_tmp = NULL;
        
        p_node_tmp = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
        while (i_pos <= i_pos_index)
        {
            Frlist_node *p_node_next = NULL;
            if (!p_node_tmp || !p_node_tmp->data)
                break;
            p_node_next = FRLIST_NEXT_NODE(p_node_tmp);
            //总长度需要减去脱链的(当前位置之前的)节点的长度
            p_bytebuffer_tmp = (Frbyte_buffer *)p_node_tmp->data;
            p_packet->ui_all_len -= p_bytebuffer_tmp->ui_len;
            frlist_node_free(p_packet->p_lst_bytebuffer, p_node_tmp, FR_YES, __bytebuff_node_free);
            p_node_tmp = p_node_next;
            i_pos++;
        }
    }
    
    //添加修改过的节点到链表的头节点上
    if (i_left || p_buff)
    {
        Frlist_node *p_node_new = NULL;
        Frbyte_buffer *p_bytebuff_new = NULL;
        
        p_bytebuff_new = (Frbyte_buffer *)frmalloc(sizeof(Frbyte_buffer));
        if (!p_bytebuff_new)
        {
            if (p_buff)
                frfree(p_buff);
            return FR_FAIL;
        }
        p_bytebuff_new->pos = 0;
        p_bytebuff_new->ui_len = i_left;
        p_bytebuff_new->p_buf = p_buff;
        p_node_new = frlist_node_create(p_bytebuff_new);
        if (!p_node_new)
        {
            if (p_buff)
                frfree(p_buff);
            frfree(p_bytebuff_new);
            return FR_FAIL;
        }
        frlist_add_header(p_packet->p_lst_bytebuffer, p_node_new);
        //总长度加上添加的链表节点
        p_packet->ui_all_len += i_left;
    }
    p_packet->pos_index = 0;
    p_packet->p_node_index = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    
    return FR_SUCC;
}

int bytebuff_getPosition(Frbyte_Packet *p_packet)
{
    if (p_packet)
        return p_packet->ui_all_len - p_packet->ui_remaining;
    return -1;
}

int bytebuff_setPosition(Frbyte_Packet *p_packet, int i_pos)
{
    unsigned int ui_len = 0;
    uint32_t ui_pos_index_tmp = 0;
    Frlist_node *p_node = NULL;
    
    if (!p_packet)
        return FR_FAIL;
    
    //设置为初始位置，即bytebuff_rewind
    if (i_pos == 0)
    {
        bytebuff_rewind(p_packet);
        p_packet->ui_remaining = p_packet->ui_all_len;
        p_packet->p_node_index = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
        return FR_SUCC;
    }
    
    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    while (p_node && p_node->data)
    {
        Frbyte_buffer *p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (ui_len + p_bytebuffer->ui_len >= i_pos)
        {
            //先把之前的pos位置清除掉
            bytebuff_rewind(p_packet);
            
            p_bytebuffer->pos = i_pos - ui_len;
            p_packet->pos_index = ui_pos_index_tmp;
            p_packet->ui_remaining = p_packet->ui_all_len - i_pos;
            p_packet->p_node_index = p_node;
            return FR_SUCC;
        }
        ui_len += p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
        ui_pos_index_tmp++;
    }
    p_packet->ui_remaining = p_packet->ui_all_len - i_pos;
    
    return FR_FAIL;
}

int bytebuff_setPositionEnd(Frbyte_Packet *p_packet)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;

    if (!p_packet)
        return FR_FAIL;

    p_node = FRLIST_LAST_NODE(p_packet->p_lst_bytebuffer);
    if (!p_node)
        return FR_FAIL;

    p_bytebuffer = (Frbyte_buffer *)p_node->data;
    p_bytebuffer->pos = p_bytebuffer->ui_len;

    p_packet->pos_index = frlist_size(p_packet->p_lst_bytebuffer) - 1;
    p_packet->p_node_index = p_node;
    p_packet->ui_remaining = 0;

    return FR_SUCC;
}

int bytebuff_peek_bytes(Frbyte_Packet *p_packet, void *p_outbuf, unsigned int ui_len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    int i_left = 0, i_copy = 0;
    
    if (!p_packet || !p_outbuf || ui_len == 0 || !p_packet->p_node_index)
        return FR_FAIL;
    
    //取得当前节点
    p_bytebuffer = (Frbyte_buffer *)p_packet->p_node_index->data;
    //需要取得的长度不超过当前包
    if (p_bytebuffer->pos + ui_len <= p_bytebuffer->ui_len)
    {
        memcpy(p_outbuf, p_bytebuffer->p_buf + p_bytebuffer->pos, ui_len);
        return FR_SUCC;
    }
    i_copy = p_bytebuffer->ui_len - p_bytebuffer->pos;
    i_left = ui_len - i_copy;
    //需要取得的长度超过当前包，取后面的包
    if (i_copy)
    {
        //当前节点的值为NULL，即为skip的内容，取不到内容，返回失败
        if (!p_bytebuffer->p_buf)
            return FR_FAIL;
        memcpy(p_outbuf, p_bytebuffer->p_buf + p_bytebuffer->pos, i_copy);
    }
    
    p_node = FRLIST_NEXT_NODE(p_packet->p_node_index);
    while (p_node && p_node->data)
    {
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        //当前节点的值为NULL，即为skip的内容，取不到内容，返回失败
        if (!p_bytebuffer->p_buf)
            return FR_FAIL;
        //正常逻辑,拷贝完所有需要的内容
        if (p_bytebuffer->pos + i_left <= p_bytebuffer->ui_len)
        {
            memcpy((char *)p_outbuf + i_copy, p_bytebuffer->p_buf, i_left);
            return FR_SUCC;
        }
        memcpy((char *)p_outbuf + i_copy, p_bytebuffer->p_buf, p_bytebuffer->ui_len);
        i_copy += p_bytebuffer->ui_len;
        i_left -= p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    
    return FR_FAIL;
}

int bytebuff_get_bytes(Frbyte_Packet *p_packet, void *p_outbuf, unsigned int ui_len)
{
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    int i_left = 0, i_copy = 0, i_pos_index = 0;
    int i_old_pos = 0;
    
    if (!p_packet || !p_outbuf || !p_packet->p_node_index)
        return FR_FAIL;
    
    //取得当前节点
    p_bytebuffer = (Frbyte_buffer *)p_packet->p_node_index->data;
    
    i_old_pos = p_bytebuffer->pos;
    //需要取得的长度不超过当前包
    if (p_bytebuffer->pos + ui_len <= p_bytebuffer->ui_len)
    {
        //当前节点的值为NULL，即为skip的内容，取不到内容，返回失败
        if (!p_bytebuffer->p_buf)
            return FR_FAIL;
        memcpy(p_outbuf, p_bytebuffer->p_buf + p_bytebuffer->pos, ui_len);
        p_bytebuffer->pos += ui_len;
        p_packet->ui_remaining -= ui_len;
        return FR_SUCC;
    }
    i_pos_index = p_packet->pos_index;
    i_copy = p_bytebuffer->ui_len - p_bytebuffer->pos;
    i_left = ui_len - i_copy;
    //需要取得的长度超过当前包，取后面的包
    if (i_copy)
    {
        //当前节点的值为NULL，即为skip的内容，取不到内容，返回失败
        if (!p_bytebuffer->p_buf)
            return FR_FAIL;
        memcpy(p_outbuf, p_bytebuffer->p_buf + p_bytebuffer->pos, i_copy);
    }
    p_bytebuffer->pos = 0;
    
    p_node = FRLIST_NEXT_NODE(p_packet->p_node_index);
    while (p_node && p_node->data)
    {
        i_pos_index++;
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        //当前节点的值为NULL，即为skip的内容，取不到内容，返回失败
        if (!p_bytebuffer->p_buf)
            goto failed;
        //正常逻辑,拷贝完所有需要的内容
        if (p_bytebuffer->pos + i_left <= p_bytebuffer->ui_len)
        {
            memcpy((char *)p_outbuf + i_copy, p_bytebuffer->p_buf, i_left);
            p_bytebuffer->pos = i_left;
            p_packet->pos_index = i_pos_index;
            p_packet->ui_remaining -= ui_len;
            p_packet->p_node_index = p_node;
            return FR_SUCC;
        }
        memcpy((char *)p_outbuf + i_copy, p_bytebuffer->p_buf, p_bytebuffer->ui_len);
        p_bytebuffer->pos = 0;
        i_copy += p_bytebuffer->ui_len;
        i_left -= p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
failed:
    //rollback 原来的位置
    p_node = frlist_node_idx(p_packet->p_lst_bytebuffer, p_packet->pos_index);
    p_bytebuffer = (Frbyte_buffer *)p_node->data;
    p_bytebuffer->pos = i_old_pos;
    
    return FR_FAIL;
}

FR_STATIC int __parse_endian(char *p_in, int i_inlen, int i_real_len, LITTLE_BIG_ENDIAN i_endian, char **pp_out)
{
    int i_loop = 0;
    char *p_out = NULL;

    p_out = (char *)frmalloc(i_inlen);
    if (p_out == NULL)
        return FR_FAIL;
    
    memset(p_out, 0x00, i_inlen);

    if (i_endian == BYTE_LITTLE_ENDIAN)
    {
        //小头 0503 == 05030000
        for (i_loop=0;i_loop<i_real_len;i_loop++)
        {
            memcpy(p_out + i_loop, p_in + i_loop, 1);
        }
    }
    else
    {
        //大头 0305 == 00000305
        for (i_loop=0;i_loop<i_real_len;i_loop++)
        {
            memcpy(p_out + (i_inlen-i_real_len) + i_loop, p_in + i_loop, 1);
        }
    }
    *pp_out = p_out;
    return FR_SUCC;
}

int bytebuff_peek_int(Frbyte_Packet *p_packet, int i_len, uint32_t *p_i_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint32_t)] = {'\0'};
    char *p_i_out = NULL;
    uint32_t *p_i_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint32_t))
        return FR_FAIL;
    
    if (bytebuff_peek_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint32_t), i_len, i_endian, &p_i_out) != FR_SUCC && p_i_out != NULL)
        return FR_FAIL;
        
    p_i_tmp = (uint32_t *)p_i_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_i_data = be32toh(*p_i_tmp);
    else
        *p_i_data = le32toh(*p_i_tmp);
    
    frfree(p_i_out);
    
    return FR_SUCC;
}

int bytebuff_get_int(Frbyte_Packet *p_packet, int i_len, uint32_t *p_i_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint32_t)] = {'\0'};
    char *p_i_out = NULL;
    uint32_t *p_i_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint32_t))
        return FR_FAIL;
    
    if (bytebuff_get_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint32_t), i_len, i_endian, &p_i_out) != FR_SUCC && p_i_out != NULL)
        return FR_FAIL;
        
    p_i_tmp = (uint32_t *)p_i_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_i_data = be32toh(*p_i_tmp);
    else
        *p_i_data = le32toh(*p_i_tmp);
    
    frfree(p_i_out);
    
    return FR_SUCC;
}

int bytebuff_peek_long(Frbyte_Packet *p_packet, int i_len, uint64_t *p_l_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint64_t)] = {'\0'};
    char *p_l_out = NULL;
    uint64_t *p_l_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint64_t))
        return FR_FAIL;
    
    if (bytebuff_peek_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint64_t), i_len, i_endian, &p_l_out) != FR_SUCC && p_l_out != NULL)
        return FR_FAIL;
        
    p_l_tmp = (uint64_t *)p_l_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_l_data = be64toh(*p_l_tmp);
    else
        *p_l_data = le64toh(*p_l_tmp);
    
    frfree(p_l_out);
    
    return FR_SUCC;
}

int bytebuff_get_long(Frbyte_Packet *p_packet, int i_len, uint64_t *p_l_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint64_t)] = {'\0'};
    char *p_l_out = NULL;
    uint64_t *p_l_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint64_t))
        return FR_FAIL;
    
    if (bytebuff_get_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint64_t), i_len, i_endian, &p_l_out) != FR_SUCC && p_l_out != NULL)
        return FR_FAIL;
        
    p_l_tmp = (uint64_t *)p_l_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_l_data = be64toh(*p_l_tmp);
    else
        *p_l_data = le64toh(*p_l_tmp);
    
    frfree(p_l_out);
    
    return FR_SUCC;
}

int bytebuff_peek_short(Frbyte_Packet *p_packet, int i_len, uint16_t *p_s_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint16_t)] = {'\0'};
    char *p_s_out = NULL;
    uint16_t *p_s_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint16_t))
        return FR_FAIL;
    
    if (bytebuff_peek_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint16_t), i_len, i_endian, &p_s_out) != FR_SUCC && p_s_out != NULL)
        return FR_FAIL;
        
    p_s_tmp = (uint16_t *)p_s_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_s_data = be16toh(*p_s_tmp);
    else
        *p_s_data = le16toh(*p_s_tmp);
    
    frfree(p_s_out);
    
    return FR_SUCC;
}

int bytebuff_get_short(Frbyte_Packet *p_packet, int i_len, uint16_t *p_s_data, LITTLE_BIG_ENDIAN i_endian)
{
    char arr_out[sizeof(uint16_t)] = {'\0'};
    char *p_s_out = NULL;
    uint16_t *p_s_tmp = NULL;
    
    if (!p_packet || i_len == 0 || i_len > sizeof(uint16_t))
        return FR_FAIL;
    
    if (bytebuff_get_bytes(p_packet, arr_out, i_len) != FR_SUCC)
        return FR_FAIL;
    
    //根据大小端来解析取得的值
    if (__parse_endian(arr_out, sizeof(uint16_t), i_len, i_endian, &p_s_out) != FR_SUCC && p_s_out != NULL)
        return FR_FAIL;
        
    p_s_tmp = (uint16_t *)p_s_out;
    if (i_endian == BYTE_BIG_ENDIAN)
        *p_s_data = be16toh(*p_s_tmp);
    else
        *p_s_data = le16toh(*p_s_tmp);
    
    frfree(p_s_out);
    
    return FR_SUCC;
}

int bytebuff_peek_char(Frbyte_Packet *p_packet, uint8_t *p_char)
{
    return bytebuff_peek_bytes(p_packet, p_char, sizeof(uint8_t));
}

int bytebuff_get_char(Frbyte_Packet *p_packet, uint8_t *p_char)
{
    return bytebuff_get_bytes(p_packet, p_char, sizeof(uint8_t));
}

int bytebuffer_get_at(Frbyte_Packet *p_packet, int i_pos, uint8_t *p_c_data)
{
    unsigned int ui_len = 0;
    Frlist_node *p_node = NULL;
    
    if (!p_packet)
        return FR_FAIL;
    
    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    while (p_node && p_node->data)
    {
        Frbyte_buffer *p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (ui_len + p_bytebuffer->ui_len >= 1 && (ui_len + p_bytebuffer->ui_len - 1 >= i_pos))
        {
            if (p_bytebuffer->p_buf == NULL)
                return FR_FAIL;
            
            memcpy(p_c_data, p_bytebuffer->p_buf + i_pos - ui_len, sizeof(uint8_t));
            return FR_SUCC;
        }
        ui_len += p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    return FR_FAIL;
}

int bytebuff_get_bytes_at(Frbyte_Packet *p_packet, int i_pos_from, unsigned int ui_getlen, void *p_outbuf)
{
    unsigned int ui_len = 0;
    unsigned int ui_copy = 0;
    int i_left = 0;
    Frlist_node *p_node = NULL;
    
    if (!p_packet || !p_outbuf)
        return FR_FAIL;
    
    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    while (p_node && p_node->data)
    {
        Frbyte_buffer *p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (ui_len + p_bytebuffer->ui_len >= i_pos_from)
        {
            unsigned int ui_start = 0;
            if (p_bytebuffer->p_buf == NULL)
                return FR_FAIL;
            
            //当前数据块开始拷贝的位置
            ui_start = i_pos_from - ui_len;
            ui_copy = p_bytebuffer->ui_len - ui_start > ui_getlen ? ui_getlen : p_bytebuffer->ui_len - ui_start;
            i_left = ui_getlen - ui_copy;
            
            if (ui_copy)
            {
                memcpy(p_outbuf, p_bytebuffer->p_buf + ui_start, ui_copy);
                if (i_left <= 0)
                    return FR_SUCC;
            }
            
            p_node = FRLIST_NEXT_NODE(p_node);
            while (p_node && p_node->data)
            {
                p_bytebuffer = (Frbyte_buffer *)p_node->data;
                if (p_bytebuffer->p_buf == NULL)
                    return FR_FAIL;
                //正常逻辑,拷贝完所有需要的内容
                if (p_bytebuffer->ui_len > i_left)
                {
                    memcpy((char *)p_outbuf + ui_copy, p_bytebuffer->p_buf, i_left);
                    return FR_SUCC;
                }
                memcpy((char *)p_outbuf + ui_copy, p_bytebuffer->p_buf, p_bytebuffer->ui_len);
                i_left -= p_bytebuffer->ui_len;
                ui_copy += p_bytebuffer->ui_len;
                p_node = FRLIST_NEXT_NODE(p_node);
            }
            return FR_SUCC;
        }
        ui_len += p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    return FR_FAIL;
}


FR_STATIC int __memstr(Frlist_node *p_node, char *p_from, int i_from_len, const char *p_sub, int i_sub_len)
{
    int i_compare = 0;
    int i_done = 0;
    char* p_tmp = p_from;
    Frbyte_buffer *p_bytebuffer = NULL;
    
    i_compare = i_from_len > i_sub_len ? i_sub_len : i_from_len;
    
    while (p_tmp)
    {
        if (memcmp(p_tmp, p_sub + i_done, i_compare))
            return FR_FAIL;
        
        i_done += i_compare;
        if (i_done == i_sub_len)
            return FR_SUCC;
        p_node = FRLIST_NEXT_NODE(p_node);
        if (p_node == NULL)
            break;
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        p_tmp = p_bytebuffer->p_buf;
        i_compare = p_bytebuffer->ui_len > i_sub_len - i_done ? i_sub_len - i_done : p_bytebuffer->ui_len;
    }
    return FR_FAIL;
}

int bytebuff_memstr(Frbyte_Packet *p_packet, int i_pos, int i_endpos, const char *p_substr, int i_sublen, int *p_i_found)
{
    int i_done = 0, i_node_left = 0, i_left = 0, i_node_all = 0;
    char *p_node_data = NULL;
    Frlist_node *p_node = NULL;
    Frbyte_buffer *p_bytebuffer = NULL;
    int i_node_tmp = 0, i_pos_tmp = 0;
    
    if (p_packet == NULL || i_pos < 0 || i_endpos < 0 
     || p_substr == NULL || i_sublen <= 0 || p_packet->ui_all_len < i_sublen)
        return FR_FAIL;
    
    if (i_endpos != 0 && i_endpos <= i_pos)
        return FR_FAIL;
    
    i_left = p_packet->ui_all_len;
    
    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    
    while (p_node)
    {
        p_bytebuffer = (Frbyte_buffer *)p_node->data;
        p_node_data = p_bytebuffer->p_buf;
        i_node_all = p_bytebuffer->ui_len;
        i_node_left = i_node_all;
        //判断此节点的内容是否为NULL,为NULL跳过此节点
        if (p_node_data == NULL || i_pos > i_node_left)
        {
            i_left -= i_node_left;
            i_pos -= i_node_left;
            p_node = FRLIST_NEXT_NODE(p_node);
            if (i_left < i_sublen)
                return FR_FAIL;
            i_node_tmp += p_bytebuffer->ui_len;
            continue;
        }
        
        //找到开始位置,从开始位置来做比较
        if (i_pos)
        {
            p_node_data += i_pos;
            i_node_left -= i_pos;
            i_node_all -= i_pos;
            i_left -= i_pos;
            i_node_tmp += i_pos;
            i_pos_tmp = i_pos;
            i_pos = 0;
        }
        
        //从此节点开始找
        for (i_done = 0;i_done < i_node_all;i_done++)
        {
            if (*(p_node_data + i_done) == *p_substr)
            {
                if (__memstr(p_node, p_node_data + i_done, i_node_left, p_substr, i_sublen) == FR_SUCC)
                {
                    *p_i_found = i_node_tmp + i_node_all - i_node_left;
                    return FR_SUCC;
                }
            }
            i_left--;
            
            //是否结束查找
            if (i_endpos !=0)
            {
                if (p_packet->ui_all_len - i_left + i_sublen > i_endpos)
                    return FR_FAIL;
            }
            else
            {
                if (i_left < i_sublen)
                    return FR_FAIL;
            }
            i_node_left--;
        }
        //是否结束查找
        if (i_endpos !=0)
        {
            if (p_packet->ui_all_len - i_left + i_sublen > i_endpos)
                return FR_FAIL;
        }
        else
        {
            if (i_left < i_sublen)
                return FR_FAIL;
        }
        i_node_tmp += p_bytebuffer->ui_len - i_pos_tmp;
        i_pos_tmp = 0;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    return FR_FAIL;
}

int bytebuff_print(Frbyte_Packet *p_packet, int i_pos, int i_len, char **pp_out)
{
    unsigned int ui_len = 0;
    int i_used = 0, i_exit = 0;
    Frlist_node *p_node = NULL;
    char *p_out = NULL;
    char *p_out_tmp = NULL;
    
    if (!p_packet)
        return FR_FAIL;
    
    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    while (p_node && p_node->data)
    {
        Frbyte_buffer *p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (ui_len + p_bytebuffer->ui_len >= i_pos)
        {
            unsigned int ui_start = 0;
            unsigned int ui_print = 0;
            
            if (p_bytebuffer->p_buf == NULL)
                return FR_FAIL;
            
            //开始打印的位置
            ui_start = i_pos - ui_len;
            //是否已经到达需要打印的长度
            ui_print = p_bytebuffer->ui_len - ui_start;
            if (ui_print + i_used > i_len)
            {
                ui_print = i_len - i_used;
                i_exit = 1;
            }
            i_used += ui_print;
            
            if (frhex_dump_to_buffer(p_bytebuffer->p_buf + ui_start, ui_print, &p_out_tmp) != 0 || p_out_tmp == NULL)
                return FR_FAIL;
            
            p_out = p_out_tmp;
            //到达需要打印的长度，程序结束
            if (i_exit)
            {
                *pp_out = p_out;
                return FR_SUCC;
            }
            
            p_node = FRLIST_NEXT_NODE(p_node);
            while (p_node && p_node->data)
            {
                char *p_new = NULL;
                p_bytebuffer = (Frbyte_buffer *)p_node->data;
                //把所有数据块中2进制的显示的内容合并起来
                if (p_bytebuffer->p_buf)
                {
                    char *p_remalloc = NULL;
                    unsigned int ui_all = 0;
                    ui_print = p_bytebuffer->ui_len;
                    
                    //判断是否已经读完
                    if (ui_print + i_used > i_len)
                    {
                        ui_print = i_len - i_used;
                        i_exit = 1;
                    }
                    i_used += ui_print;
                    
                    //取得这个节点的2进制打印数据
                    if (frhex_dump_to_buffer(p_bytebuffer->p_buf, ui_print, &p_new) != 0)
                        goto err;
                    
                    //数据合并
                    ui_all = strlen(p_out) + strlen(p_new);
                    p_remalloc = (char *)frmalloc(ui_all + 1);
                    if (!p_remalloc)
                    {
                        frfree(p_new);
                        goto err;
                    }
                    snprintf(p_remalloc, ui_all + 1, "%s%s", p_out, p_new);
                    frfree(p_out);
                    frfree(p_new);
                    p_new = NULL;
                    p_out = p_remalloc;
                    if (i_exit)
                    {
                        *pp_out = p_out;
                        return FR_SUCC;
                    }
                }
                //todo
                //skip的数据(不打印出来?)
                else
                {
                    i_used += p_bytebuffer->ui_len;
                    if (i_used > i_len)
                    {
                        *pp_out = p_out;
                        return FR_SUCC;
                    }
                }
                p_node = FRLIST_NEXT_NODE(p_node);
            }
            *pp_out = p_out;
            
            return FR_SUCC;
        }
        ui_len += p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    return FR_FAIL;
err:
    if (p_out)
        frfree(p_out);
    return FR_FAIL;
}

int bytebuff_show(Frbyte_Packet *p_packet, int i_pos, int i_len, char **pp_out)
{
    unsigned int ui_len = 0;
    int i_used = 0, i_exit = 0;
    Frlist_node *p_node = NULL;
    char *p_out = NULL;
    char *p_out_tmp = NULL;
    int i_outlen = 0;

    if (!p_packet)
        return FR_FAIL;

    p_node = FRLIST_FIRST_NODE(p_packet->p_lst_bytebuffer);
    while (p_node && p_node->data)
    {
        Frbyte_buffer *p_bytebuffer = (Frbyte_buffer *)p_node->data;
        if (ui_len + p_bytebuffer->ui_len >= i_pos)
        {
            unsigned int ui_start = 0;
            unsigned int ui_print = 0;

            if (p_bytebuffer->p_buf == NULL)
                return FR_FAIL;

            //开始打印的位置
            ui_start = i_pos - ui_len;
            //是否已经到达需要打印的长度
            ui_print = p_bytebuffer->ui_len - ui_start;
            if (ui_print + i_used >= i_len)
            {
                ui_print = i_len - i_used;
                i_exit = 1;
            }
            i_used += ui_print;

            if (ui_print)
            {
                p_out_tmp = (char *)frmemdup(p_bytebuffer->p_buf + ui_start, ui_print);
                if (p_out_tmp == NULL)
                    return FR_FAIL;

                p_out = p_out_tmp;
                i_outlen += ui_print;
                //到达需要打印的长度，程序结束
                if (i_exit)
                {
                    *pp_out = p_out;
                    return FR_SUCC;
                }
            }

            p_node = FRLIST_NEXT_NODE(p_node);
            while (p_node && p_node->data)
            {
                char *p_new = NULL;
                p_bytebuffer = (Frbyte_buffer *)p_node->data;
                //把所有数据块中2进制的显示的内容合并起来
                if (p_bytebuffer->p_buf)
                {
                    char *p_remalloc = NULL;
                    unsigned int ui_all = 0;
                    ui_print = p_bytebuffer->ui_len;

                    //判断是否已经读完
                    if (ui_print + i_used >= i_len)
                    {
                        ui_print = i_len - i_used;
                        i_exit = 1;
                    }
                    i_used += ui_print;

                    //取得这个节点的2进制打印数据
                    p_new = (char *)frmemdup(p_bytebuffer->p_buf, ui_print);
                    if (p_new == NULL)
                        goto err;

                    //数据合并
                    ui_all = i_outlen + ui_print;
                    p_remalloc = (char *)frmalloc(ui_all);
                    if (!p_remalloc)
                    {
                        frfree(p_new);
                        goto err;
                    }
                    if (p_out)
                        memcpy(p_remalloc, p_out, i_outlen);
                    memcpy(p_remalloc+i_outlen, p_new, ui_print);
                    i_outlen = ui_all;
                    frfree(p_out);
                    frfree(p_new);
                    p_new = NULL;
                    p_out = p_remalloc;
                    if (i_exit)
                    {
                        *pp_out = p_out;
                        return FR_SUCC;
                    }
                }
                //todo
                //skip的数据(不打印出来?)
                else
                {
                    i_used += p_bytebuffer->ui_len;
                    if (i_used > i_len)
                    {
                        *pp_out = p_out;
                        return FR_SUCC;
                    }
                }
                p_node = FRLIST_NEXT_NODE(p_node);
            }
            *pp_out = p_out;

            return FR_SUCC;
        }
        ui_len += p_bytebuffer->ui_len;
        p_node = FRLIST_NEXT_NODE(p_node);
    }
    *pp_out = p_out;
    return FR_SUCC;
err:
    if (p_out)
        frfree(p_out);
    return FR_FAIL;
}
